﻿using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace XiphMediaEncoder
{
   public static class TemplateValidator
   {
      public static string ValidateFilenameTemplate(string template)
      {
         if (template.Length == 0)
            return null;

         // Vérification de la syntaxe du modèle
         int j = template.Count(t => t == '|');

         if (j < 2 || (j % 2 != 0))
            return "There is a syntax error in template.";

         // Vérification du nom des tags utilisés
         var sb = new StringBuilder(template);
         MatchCollection mc = Regex.Matches(template, @"\|.*?\|");
         foreach (Match m in mc)
         {
            sb.Replace(m.Value, null);
            string[] invalidVorbisTagChars;
            if (TagNormalizer.ContainsInvalidChar(m.Value, out invalidVorbisTagChars))
               return String.Format("A tag name contains the following invalid characters: {0}", String.Join(", ", invalidVorbisTagChars));
         }

         // Vérification du nom de fichier
         sb.Replace("|", null);
         string[] invalidFilenameChars;
         if (PathNormalizer.ContainsInvalidCharInFilename(sb.ToString(), out invalidFilenameChars))
            return String.Format("The filename contains the following invalid characters: {0}", String.Join(", ", invalidFilenameChars));

         return null;
      }      

      public static string ValidatePathTemplate(string template)
      {
         if (template.Length == 0)
            return null;

         // Vérification de la syntaxe du modèle
         int j = template.Count(t => t == '|');

         if (j < 2 || (j % 2 != 0))
            return "There is a syntax error in template.";

         // Vérification du nom des tags utilisés
         var sb = new StringBuilder(template);
         MatchCollection mc = Regex.Matches(template, @"\|.*?\|");
         foreach (Match m in mc)
         {
            sb.Replace(m.Value, null);
            string[] invalidVorbisTagChars;
            if (TagNormalizer.ContainsInvalidChar(m.Value, out invalidVorbisTagChars))
               return String.Format("A tag name contains the following invalid characters: {0}", String.Join(", ", invalidVorbisTagChars));
         }

         // Vérification du chemin
         sb.Replace("|", null);
         string[] invalidFilenameChars;
         if (PathNormalizer.ContainsInvalidCharInPath(sb.ToString(), out invalidFilenameChars))
            return String.Format("The filename contains the following invalid characters: {0}", String.Join(", ", invalidFilenameChars));

         return null;
      }

      public static string ValidateRenameTemplate(string template)
      {
         if (template.Length == 0)
            return null;

         // Vérification de la syntaxe du modèle
         int j = 0;
         int k = 0;
         foreach (char t in template)
         {
            switch (t)
            {
               case '|':
                  j++;
                  break;
               case '<':
                  k++;
                  break;
               case '>':
                  k--;
                  if (k < 0)
                     return "There is a syntax error in template.";
                  break;
            }
         }

         if (j < 2 || (j % 2 != 0) || k != 0)
            return "There is a syntax error in template.";

         // Vérification du nom des tags utilisés
         var sb = new StringBuilder(template);
         MatchCollection mc = Regex.Matches(template, @"\|.*?\|");
         foreach (Match m in mc)
         {
            sb.Replace(m.Value, null);
            string[] invalidVorbisTagChars;
            if (TagNormalizer.ContainsInvalidChar(m.Value, out invalidVorbisTagChars))
               return String.Format("A tag name contains the following invalid characters: {0}", String.Join(", ", invalidVorbisTagChars));
         }

         // Vérification du nom de fichier
         sb.Replace("|", null);
         sb.Replace("<", null);
         sb.Replace(">", null);
         string[] invalidFilenameChars;
         if (PathNormalizer.ContainsInvalidCharInFilename(sb.ToString(), out invalidFilenameChars))
            return String.Format("The filename contains the following invalid characters: {0}", String.Join(", ", invalidFilenameChars));

         return null;
      }

      public static string ValidateOrganizeTemplate(string template)
      {
         if (template.Length == 0)
            return null;

         // Vérification de la syntaxe du modèle
         int j = 0;
         int k = 0;
         foreach (char t in template)
         {
            switch (t)
            {
               case '|':
                  j++;
                  break;
               case '<':
                  k++;
                  break;
               case '>':
                   k--;
                  if (k < 0)
                     return "There is a syntax error in template.";
                  break;
            }
         }

         if ((j % 2 != 0) || k != 0)
            return "There is a syntax error in template.";

         // Vérification du nom des tags utilisés
         var sb = new StringBuilder(template);
         MatchCollection mc = Regex.Matches(template, @"\|.*?\|");
         foreach (Match m in mc)
         {
            sb.Replace(m.Value, null);
            string[] invalidVorbisTagChars;
            if (TagNormalizer.ContainsInvalidChar(m.Value, out invalidVorbisTagChars))
               return String.Format("A tag name contains the following invalid characters: {0}", String.Join(", ", invalidVorbisTagChars));
         }

         // Vérification de la syntaxe initiale du chemin
         if (!PathNormalizer.IsValidRootPath(template))
            return "The path is invalid.";

         // Vérification du chemin
         sb.Replace("|", null);
         sb.Replace("<", null);
         sb.Replace(">", null);
         string[] invalidFilenameChars;
         if (PathNormalizer.ContainsInvalidCharInPath(sb.ToString(), out invalidFilenameChars))
            return String.Format("The filename contains the following invalid characters: {0}", String.Join(", ", invalidFilenameChars));

         return null;
      }      
   }
}